/*
 * Copyright (c) 1999-2009 InfoReach, Inc. All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * InfoReach ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with InfoReach.
 *
 * CopyrightVersion 2.0
 *
 */
package com.inforeach.util.string;

/**
 * 
 * @author dmytros
 */
public class SimpleEscapingStringTransformer implements IStringTransformer
{
    public static final String DEFAULT_SPEC = "\\\nn\rr\ff\tt\bb";

    private final char esc_;
    private final char[][] arr_;

    public SimpleEscapingStringTransformer()
    {
        this(DEFAULT_SPEC);
    }

    public SimpleEscapingStringTransformer(String spec)
    {
        int l = spec.length();
        if ((l & 1) == 0)
        {
            throw new IllegalArgumentException(spec);
        }
        int n = l >> 1;
        arr_ = new char[2][n + 1];
        esc_ = spec.charAt(0);
        arr_[0][0] = esc_;
        arr_[1][0] = esc_;
        for (int i = 0; i < n; ++i)
        {
            arr_[0][i + 1] = spec.charAt((i << 1) + 1);
            arr_[1][i + 1] = spec.charAt((i << 1) + 2);
        }
    }

    @Override
    public String forward(String str)
    {
        if (str == null) return str;
        StringBuilder builder = null;
        for (int i = 0; i < str.length(); ++i)
        {
            char ch = str.charAt(i);
            int idx = indexOf(arr_[0], ch);
            if (idx >= 0)
            {
                if (builder == null)
                {
                    builder = new StringBuilder(str.length() + 1);
                    builder.append(str, 0, i);
                }
                builder.append(esc_).append(arr_[1][idx]);
            }
            else
            {
                if (builder != null) builder.append(ch);
            }
        }
        return builder != null ? builder.toString() : str;
    }

    @Override
    public String reverse(String str)
    {
        if (str == null) return str;
        StringBuilder builder = null;
        for (int i = 0; i < str.length(); ++i)
        {
            char ch = str.charAt(i);
            if (ch == esc_)
            {
                ++i;
                if (i < str.length())
                {
                    char ch2 = str.charAt(i);
                    int idx = indexOf(arr_[1], ch2);
                    if (idx >= 0)
                    {
                        if (builder == null)
                        {
                            builder = new StringBuilder(str.length() - 1);
                            builder.append(str, 0, i - 1);
                        }
                        builder.append(arr_[0][idx]);
                    }
                    else
                    {
                        if (builder != null) builder.append(ch).append(ch2);
                    }
                }
                else
                {
                    if (builder != null) builder.append(ch);
                }
            }
            else
            {
                if (builder != null) builder.append(ch);
            }
        }
        return builder != null ? builder.toString() : str;
    }

    int indexOf(char[] arr, char ch)
    {
        for (int i = 0; i < arr.length; ++i)
        {
            if (arr[i] == ch) return i;
        }
        return -1;
    }

}
